<?php
namespace app\crontab\controller;

use app\common\model\Declaration;
use app\common\model\User;
use time\ChangeTime;

class Wechat
{
    private $nextNewYear;
    private $nextNewYearDiffDay;
    private $config;
    private $userList;
    private $access_token;
    private $weatherData;
    private $nowYear;
    private $nowMonth;
    private $nowDay;
    private $nowWeek;
    private $nowTime;
    private $lovePrattle;
    private $declaration;
    private $requestLovePrattleNum = 1;

    public function pushGoodMorning() {
        try{
            // 获取时间
            $this->getTime();
            // 获取配置与用户信息
            $this->getConfig();
            // 获取情话内容
//            $this->getLovePrattle();
            // 随机取出一条数据信息
            $this->getDeclaration();

            // 发送
            foreach ($this->userList as $user) {
                $this->main($user);
            }
            echo '运行完成';exit;
        }catch(\Exception $e){
            echo json_encode(['Line' => $e->getLine(),'File' => $e->getFile(),'Message' => $e->getMessage()]);exit;
        }
    }

    /**
     * Notes: 获取时间信息
     */
    private function getTime() {
        $time = new ChangeTime();
        $this->nowYear = date('Y');
        $this->nowMonth = date('m');
        $this->nowDay = date('d');
        $this->nowTime = time();
        $this->nowWeek = config('week')[date("w", $this->nowTime)];
        $this->nextNewYear = implode('-', $time->convertLunarToSolar($this->nowYear + 1,1,1));
        $this->nextNewYearDiffDay = (strtotime($this->nextNewYear) - $this->nowTime) / 86400;


    }

    /**
     * Notes: 获取配置
     */
    private function getConfig(){
        $this->config = config('WechatGoodMorning');

        // 获取accessToken
        $this->getAccessToken();

        $userModel = new User();
        $query['queryMode'] = 'list';
        $query['where'] = ['is_del' => 0, ];
        $list = $userModel->getBaseQuery($query);
        $userList = [];

        $beforeNewYear = (strtotime($this->nextNewYear) - $this->nowTime) / 86400;
        foreach($list as $key => $value) {
            $userList[$key]['open_id'] = $value['open_id'];
            $userList[$key]['new_year'] = (int)$beforeNewYear;
            $userList[$key]['birthday'] = $this->getUserBirthday($value['gregorian_birthday'], $value['lunar_birthday']);
            $userList[$key]['city'] = $value['city'];
        }

        $this->userList = $userList;
    }
    /**
     * Notes: 获取用户下一个生日
     */
    private function getUserBirthday($gregorianBirthday, $lunarBirthday) {
        // 填写了阳历，则优先
        if($gregorianBirthday != '0.00') {
            // 判断今年生日过了没有
            if((float)$gregorianBirthday < (float)$this->nowMonth. '.'. $this->nowDay) {
                $birthday = ($this->nowYear + 1). '.'. $gregorianBirthday;
            }else {
                $birthday = $this->nowYear. '.'. $gregorianBirthday;
            }
        }else {
            // 获取今年农历生日，用来判断是否当前年生日已过
            $time = new ChangeTime();
            $nowLunarDay = $time->convertSolarToLunar($this->nowYear,$this->nowMonth,$this->nowDay);
            $month = substr($lunarBirthday, 0, strpos($lunarBirthday,'.'));
            $day = substr($lunarBirthday, strpos($lunarBirthday,'.') + 1);
            if(strlen($nowLunarDay[5]) == 1) {
                $nowLunarDay[5] = '0'. $nowLunarDay[5];
            }

            // 获取当前年的闰月
            $nowYearLeapMonth = $time->getLeapMonth($nowLunarDay[0]);

            $year = $nowLunarDay[0];
            if($nowYearLeapMonth == $month) {
                // 生日正好今年是闰月份，一年两次生日
                $birthday = $time->convertLunarToSolar($nowLunarDay[0],$month,$day);
                $firstLeapBirthday = $birthday[0]. '-'. $birthday[1]. '-'. $birthday[2];
                if(strtotime($firstLeapBirthday) < $this->nowTime) {
                    $month = $month + 1;
                }
            }else {
                if($nowLunarDay[4] > $nowYearLeapMonth) {
                    $nowLunarDay[4] -= 1;
                }
                // 新的一年
                $nowLunary = $nowLunarDay[4]. $nowLunarDay[5];
                if(str_replace('.', '',$lunarBirthday) < $nowLunary) {
                    $year = $nowLunarDay[0] + 1;

                    // 获取新的一年的闰月   用作后面的月份判断
                    $nowYearLeapMonth = $time->getLeapMonth($year);
                }


                // 如果闰月在生日之前， 后面根据农历获取阳历时，农历数字要+1
                if($nowYearLeapMonth != 0 && $nowYearLeapMonth < $month) {
                    $month = $month + 1;
                }
            }

            $birthday = $time->convertLunarToSolar($year,$month,$day);
            $birthday = implode('.', $birthday);
        }
        return str_replace('.', '-', $birthday);
    }

    /**
     * 获取ACCESS_TOKEN
     */
    private function getAccessToken(){
        $wxgzhurl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $this->config['app_id'] . "&secret=" . $this->config['app_secret'];
        $access_token_Arr = $this->httpsRequest($wxgzhurl);
        $access_token = json_decode($access_token_Arr, true);
        $this->access_token = $access_token['access_token']; //ACCESS_TOKEN
    }

    /**
     * 获取土味情话
     */
    private function getLovePrattle() {
        // 土味情话
        $lovePrattleUrl = 'https://v2.alapi.cn/api/qinghua?token='.$this->config['alapi_token']; //修改为自己的
        $result = $this->httpsRequest($lovePrattleUrl);
        $result = json_decode($result, true);
        $this->lovePrattle = $result['data']['content'];
        if(is_null($this->lovePrattle) && $this->requestLovePrattleNum < 3) {
            $this->requestLovePrattleNum ++;
            $this->getLovePrattle();
        }
    }

    /**
     * Notes: 获取用户所在城市天气，空气情况
     */
    public function getUserCityWeather($city) {
        if(!isset($this->weatherData[$city])) {
            $weatherUrl = 'https://www.yiketianqi.com/free/day?appid='.$this->config['ke_app_id'].'&appsecret='.$this->config['ke_app_secret'].'&unescape=1&city='.$city;
            $result = $this->httpsRequest($weatherUrl);
            $result = json_decode($result, true);
            // 空气质量
            $airUrl = 'https://v0.yiketianqi.com/api?version=v10&appid='.$this->config['ke_app_id'].'&appsecret='.$this->config['ke_app_secret'].'&city='.$city;
            $AirResult = $this->httpsRequest($airUrl);
            $AirResult = json_decode($AirResult, true);
            $this->weatherData[$city] = array_merge($result,['air_level' => $AirResult['air_level'], 'air_tips' => (empty($AirResult['air_tips']) ? $AirResult['waichu'] : $AirResult['air_tips']), ]);
        }
    }

    /**
     * @param $user
     * @return void
     */
    private function main($user){
        $this->getUserCityWeather($user['city']);
        $data = $this->assemblePushData($user);

        $this->send($data);
    }

    /**
     * Notes: 组装推送数据
     */
    private function assemblePushData($user) {
        $weather = $this->weatherData[$user['city']];
        $birthday = (int)((strtotime($user['birthday']) - $this->nowTime)/86400);

        $data = [];
        $data['touser'] = $user['open_id'];
        $data['template_id'] = $this->config['template_id'];
        $prologue = $this->nowYear. '-'. $this->nowMonth. '-'. $this->nowDay. " 星期". $this->nowWeek. ' 你醒啦，早安！';
        $data['data']['prologue'] = ['value' => $prologue];
        $data['data']['weather'] = ['value' => $user['city']." ".$weather['wea']. " ". $weather['tem_night']."~".$weather['tem_day']];
        $data['data']['air'] = ['value' => $weather['air_level']];
        $data['data']['air_propose'] = ['value' => $weather['air_tips']];
        $data['data']['declaration'] = ['value' => $this->declaration];
//        $data['data']['love_prattle'] = ['value' => $this->lovePrattle];
        $data['data']['wages_five'] = ['value' => $this->getNextWagesDay(5)];
        $data['data']['wages_ten'] = ['value' => $this->getNextWagesDay(10)];
        $data['data']['wages_fifteen'] = ['value' => $this->getNextWagesDay(15)];
        $data['data']['wages_twenty'] = ['value' => $this->getNextWagesDay(20)];
        $data['data']['wages_twenty_five'] = ['value' => $this->getNextWagesDay(25)];
        $data['data']['new_year'] = ['value' => (int)$this->nextNewYearDiffDay . '天'];
        $data['data']['birthday'] = ['value' => $birthday . '天   生日：'. $user['birthday']. "\r\n"];

        return $data;
    }

    /**
     * Notes:发送
     */
    private function send($data){
        // 下面这些就不需要动了————————————————————————————————————————————————————————————————————————————————————————————
        $json_data = json_encode($data);
        $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" . $this->access_token;
        $res = $this->httpsRequest($url, urldecode($json_data));
        $res = json_decode($res, true);
        $log = '发送每日公众号推送:url:'.$url.' ,params:'.$json_data;
        if ($res['errcode'] == 0 && $res['errcode'] == "ok") {
            $log .= 'result : success';
        }else {
            $log .= 'result : error'. json_encode($res);
        }
        saveLog($log);
    }

    /**
     * @param $url
     * @param $data
     * @return bool|string
     */
    private function httpsRequest($url, $data = null)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        if (!empty($data)) {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }

    /**
     * 获取下一个发薪日
     * @param $wagesDay
     * @return int
     */
    private function getNextWagesDay($wagesDay) {
        // 获取离发薪日剩余天数

        $nowDay = $this->nowYear. '-'. $this->nowMonth. '-'. $this->nowDay;

        // 如果当前时间大于发薪日， 取下个月
        if($this->nowDay > $wagesDay) {
            $nextWagesDay = date('Y-m', strtotime("+1 month", time())). '-'. $wagesDay;
        }else {
            $nextWagesDay = $this->nowYear. '-'. $this->nowMonth. '-'. $wagesDay;
        }

        return (int)ceil((strtotime($nextWagesDay) - strtotime($nowDay)) / 86400). '天';
    }

    /**
     * 随机取出一条数据
     */
    private function getDeclaration() {
        $declarationModel = new Declaration();
        $query = [];
        $query['queryMode'] = 'info';
        $query['order'] = "rand()";
        $declarationInfo = $declarationModel->getBaseQuery($query);

        $this->declaration = empty($declarationInfo['content']) ? '' : $declarationInfo['content'];
    }
}
